<?php
declare (strict_types=1);

namespace app\controller;

use app\BaseController;
use app\common\Common;
use app\common\Sms;
use app\common\Tencent;
use app\common\UserService;
use app\model\Advise;
use app\model\AdviseClass;
use app\model\Config;
use app\model\Room;
use app\model\User;
use app\model\UserCollect;
use app\model\UserScoreLog;
use app\tool\Random;
use DateTime;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
use Exception;
use Tencent\TLSSigAPIv2;
use thans\jwt\facade\JWTAuth;
use think\db\Query;
use think\facade\Db;
use think\facade\Env;
use think\facade\Log;

class UserController extends BaseController
{
	function login()
	{
		$logintype = $this->request->post('logintype');
		$mobile = $this->request->post('mobile', '');
		$captcha = $this->request->post('captcha');
		$wechatcode = $this->request->post('wechatcode');
		$openid = '';
		switch ($logintype) {
			case 'mobile':
				if (empty($mobile) || empty($captcha)) {
					$this->writeJson(0, '手机号或验证码不能为空');
				}
				$captchaResult = Sms::check($mobile, $captcha, 'login');
				if (!$captchaResult) {
					$this->writeJson(0, '验证码错误');
				}
				$user = User::where(['mobile' => $mobile])->find();
				break;
			case 'wechat':
				if (empty($wechatcode)) {
					$this->writeJson(0, '微信code不能为空');
				}
				try {
					$openid = Common::getWechatOpenid($wechatcode);
				} catch (\Exception $e) {
					$this->writeJson(0, $e->getMessage());
				}
				$user = User::where(['openid' => $openid])->find();
				break;
			default:
				$this->writeJson(0, '登陆方式错误');
		}
		$ip = request()->ip();
		$time = time();
		if (!$user) {
			do {
				$nickname = '用户' . rand(1000000, 9999999);
			} while (User::where(['nickname' => $nickname])->find());
			do {
				$invitecode = Random::alnum();
			} while (User::where(['invitecode' => $invitecode])->find());
			
			$register_score = Config::getFieldByName('register_score', 'value');
			// 启动事务
			Db::startTrans();
			try {
				$data = [
					'mobile' => $mobile,
					'level' => 1,
					'score' => 0,
					'avatar' => '/assets/img/avatar.png',
					'openid' => $openid,
					'invitecode' => $invitecode,
					'nickname' => $nickname,
					'jointime' => $time,
					'joinip' => $ip,
					'logintime' => $time,
					'loginip' => $ip,
					'prevtime' => $time,
					'status' => 'normal',
				];
				$user = User::create($data);
				UserService::changeUserScore($register_score, $user->id, '新人注册');
				$TencentIm = Tencent::getInstance();
				$ret = json_decode($TencentIm->account_import($user->id, $user->nickname, $user->avatar));
				if ($ret->ErrorCode != 0) {
					throw new Exception('添加IM失败');
				}
		
				// 提交事务
				Db::commit();
			} catch (\Throwable $e) {
				// 回滚事务
				Db::rollback();
				$this->writeJson(0, $e->getMessage());
			}
			
			$token = JWTAuth::builder(['user_id' => $user->id]);
			if (empty($user->mobile)) {
				$this->writeJson(101, '请绑定手机号', ['Authorization' => 'Bearer ' . $token]);
			}
			if (empty($user->pid)) {
				$this->writeJson(102, '请绑定邀请码', '', 'json', ['Authorization' => 'Bearer ' . $token]);
			}
		} else {
			if ($user->status == 'hidden') {
				$this->writeJson(0, '账号被封禁');
			}
			$user->prevtime = $user->logintime;
			$user->logintime = $time;
			$user->loginip = $ip;
			$user->save();
			$token = JWTAuth::builder(['user_id' => $user->id]);
			if (empty($user->mobile)) {
				$this->writeJson(101, '请绑定手机号', ['Authorization' => 'Bearer ' . $token]);
			}
		}
		
		$this->writeJson(1, '登录成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	function register()
	{
		$mobile = $this->request->post('mobile');
		$captcha = $this->request->post('captcha');
		$invitecode = $this->request->post('invitecode');
		if (empty($mobile) || empty($captcha)) {
			$this->writeJson(0, '手机号或验证码不能为空');
		}
		if (empty($invitecode)) {
			$this->writeJson(0, '邀请码不能为空');
		}
		$captchaResult = Sms::check($mobile, $captcha, 'register');
		if (!$captchaResult) {
			$this->writeJson(0, '验证码错误');
		}
		$user = User::where(['mobile' => $mobile])->find();
		if ($user) {
			$this->writeJson(0, '该用户已注册');
		}
		$parent = User::where(['invitecode' => $invitecode])->find();
		if (!$parent) {
			$this->writeJson(0, '邀请码错误');
		}
		$register_score = Config::getFieldByName('register_score', 'value');
		$invite_score = Config::getFieldByName('invite_score', 'value');
		
		$ip = request()->ip();
		$time = time();
		do {
			$nickname = '用户' . rand(1000000, 9999999);
		} while (User::where(['nickname' => $nickname])->find());
		do {
			$invitecode = Random::alnum();
		} while (User::where(['invitecode' => $invitecode])->find());
		// 启动事务
		Db::startTrans();
		try {
			$data = [
				'mobile' => $mobile,
				'level' => 1,
				'score' => 0,
				'avatar' => '/assets/img/avatar.png',
				'invitecode' => $invitecode,
				'nickname' => $nickname,
				'jointime' => $time,
				'joinip' => $ip,
				'pid' => $parent->id,
				'logintime' => $time,
				'loginip' => $ip,
				'prevtime' => $time,
				'status' => 'normal',
			];
			$user = User::create($data);
			UserService::changeUserScore($register_score, $user->id, '新人注册');
			UserService::changeUserScore($invite_score, $parent->id, '邀请好友,注册成功');
			$TencentIm = Tencent::getInstance();
			$ret = json_decode($TencentIm->account_import($user->id, $user->nickname, $user->avatar));
			if ($ret->ErrorCode != 0) {
				throw new Exception('添加IM失败');
			}
			// 提交事务
			Db::commit();
		} catch (\Throwable $e) {
			// 回滚事务
			Db::rollback();
			$this->writeJson(0, $e->getMessage());
		}
		$this->writeJson();
	}
	
	function bindMobile()
	{
		$mobile = $this->request->post('mobile');
		$captcha = $this->request->post('captcha');
		if (empty($mobile) || empty($captcha)) {
			$this->writeJson(0, '手机号或验证码不能为空');
		}
		$captchaResult = Sms::check($mobile, $captcha, 'changemobile');
		if (!$captchaResult) {
			$this->writeJson(0, '验证码错误');
		}
		$user = User::findOrFail($this->user_id);
		$user->mobile = $mobile;
		$user->save();
		$token = JWTAuth::builder(['user_id' => $user->id]);
		if (empty($user->pid)) {
			$this->writeJson(101, '绑定邀请码', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		$this->writeJson(1, '绑定成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	function bindInvitecode()
	{
		$invitecode = $this->request->post('invitecode');
		$parent = User::where(['invitecode' => $invitecode])->find();
		if (!$parent) {
			$this->writeJson(0, '邀请码错误');
		}
		$user = User::findOrFail($this->user_id);
		if ($user->pid != 0) {
			$this->writeJson(0, '不能重复绑定');
		}
		$invite_score = Config::getFieldByName('invite_score', 'value');
		$user->pid = $parent->id;
		// 启动事务
		Db::startTrans();
		try {
			$user->save();
			UserService::changeUserScore($invite_score, $parent->id, '邀请好友,注册成功');
			// 提交事务
			Db::commit();
		}catch (\Throwable $e){
			// 回滚事务
			Db::rollback();
			$this->writeJson(0, $e->getMessage());
			
		}
		$this->writeJson();
	}
	
	
	#积分记录
	function userScore()
	{
		$status = $this->request->get('status/d'); // 0全部 1支出 2收入
		$rows = UserScoreLog::where(['user_id' => $this->user_id])->when(!empty($status), function (Query $query) use ($status) {
			if ($status == 1) {
				$query->where('score', '<=', 0);
			} else {
				$query->where('score', '>=', 0);
			}
		})->filter(function ($data) {
			if ($data->score > 0) {
				$data->score = '+' . $data->score;
			}
		})->order(['id' => 'desc'])->paginate()->items();
		$this->writeJson($rows);
	}
	
	#二维码
	function getQrCode()
	{
		$user = User::findOrFail($this->user_id);
		$writer = new PngWriter();
		$qrCode = QrCode::create(json_encode(['action' => 'user_info', 'user_id' => $user->id]))
			->setSize(100)      //大小
			->setMargin(0)             //边距
			->setForegroundColor(new Color(0, 0, 0))        //前景色
			->setBackgroundColor(new Color(255, 255, 255));       //背景色
		$result = $writer->write($qrCode)->getDataUri();
		$this->writeJson($result);
	}
	
	function getInviteImage()
	{
		$row = Config::getFieldByName('invite_image', 'value');
		if (empty($row)) {
			$this->writeJson(0, '邀请图片未设置');
		}
		$user = User::findOrFail($this->user_id);
		$writer = new PngWriter();
		$qrCode = QrCode::create(Env::get('H5_URL') . '?invitecode=' . $user->invitecode)
			->setSize(100)      //大小
			->setMargin(0)             //边距
			->setForegroundColor(new Color(0, 0, 0))        //前景色
			->setBackgroundColor(new Color(255, 255, 255));       //背景色
		$result = $writer->write($qrCode)->getDataUri();
		$this->writeJson(['qr_data' => $result, 'invitecode' => $user->invitecode, 'invite_image' => $row]);
	}
	
	function scan()
	{
		$to_user_id = $this->request->post('to_user_id/d');
		$score = $this->request->post('score/d');
		$user = User::findOrFail($this->user_id);
		if ($user->scan != 1) {
			$this->writeJson(0, '无权限访问');
		}
		try {
			UserService::changeUserScore(-$score, $to_user_id, '扫码核销');
		} catch (Exception $e) {
			$this->writeJson(102, $e->getMessage());
		}
		$this->writeJson(101, '扣除成功');
	}
	
	function getUserInfo()
	{
		$row = User::findOrFail($this->user_id);
		$this->writeJson($row);
	}
	
	function collect()
	{
		$status = $this->request->get('status/d'); #状态:1=正在进行,2=即将开始,3=已结束
		$room_ids = UserCollect::where(['user_id' => $this->user_id])->column('room_id');
		$rows = Room::whereIn('id', $room_ids)
			->when(!empty($status), function (Query $query) use ($status) {
				$query->where('status', $status);
			})
			->paginate()
			->items();
		$this->writeJson($rows);
	}
	
	/**
	 * 编辑个人信息
	 * @return void
	 */
	function userEdit()
	{
		$avatar = $this->request->post('avatar');
		$nickname = $this->request->post('nickname');
		$birthday = $this->request->post('birthday');
		$gender = $this->request->post('gender/d');//性别:1=男,2=女
		$remind = $this->request->post('remind/d');
		
		$user = User::findOrFail($this->user_id);
		$TencentIm = Tencent::getInstance();
		$info = [];
		if (!empty($avatar)) {
			$user->avatar = $avatar;
			$info[] = ['Tag' => 'Tag_Profile_IM_Image', 'Value' => $avatar];
		}
		if (!empty($nickname)) {
			$user->nickname = $nickname;
			$info[] = ['Tag' => 'Tag_Profile_IM_Nick', 'Value' => $nickname];
		}
		if (!empty($birthday)) {
			$user->birthday = $birthday;
			$date = new DateTime($birthday);
			$info[] = ['Tag' => 'Tag_Profile_IM_BirthDay', 'Value' => (int)$date->format('Ymd')];
		}
		if (!empty($gender)) {
			$user->gender = $gender;
			if ($gender == 1) {
				$info[] = ['Tag' => 'Tag_Profile_IM_Gender', 'Value' => 'Gender_Type_Male'];
			} else {
				$info[] = ['Tag' => 'Tag_Profile_IM_Gender', 'Value' => 'Gender_Type_Female'];
			}
		}
		if (!empty($remind)) {
			$user->remind = $remind;
		}
		Db::startTrans();
		try {
			$user->save();
			if (!empty($info)) {
				$ret = json_decode($TencentIm->portrait_set($user->id, $info));
				if ($ret->ErrorCode != 0) {
					throw new Exception('更新IM失败');
				}
			}
			// 提交事务
			Db::commit();
		} catch (\Throwable $e) {
			// 回滚事务
			Db::rollback();
			$this->writeJson(0, $e->getMessage());
		}
		$this->writeJson();
	}
	
	
	/**
	 * 获取腾讯ImSign
	 */
	function getImSign()
	{
		$identifier = $this->user_id;
		$im = config('wechat.im');
		$api = new TLSSigAPIv2($im['appid'], $im['secret']);
		$sig = $api->genUserSig($identifier);
		$this->writeJson($sig);
	}
	
	function getChild()
	{
		$user = User::findOrFail($this->user_id);
		$child = $user->child();
		$this->writeJson(['count' => $child->count(), 'list' => $child->paginate()->items()]);
	}
	
	function adviseClass()
	{
		$rows = AdviseClass::order(['weigh' => 'desc'])->select();
		$this->writeJson($rows);
	}
	
	/**
	 * 提建议
	 * @return void
	 */
	function adviseAdd()
	{
		$class_name = $this->request->post('class_name');
		$content = $this->request->post('content');
		$images = $this->request->post('images');
		$name = $this->request->post('name');
		$mobile = $this->request->post('mobile');
		if (empty($class_name)) {
			$this->writeJson(0, '分类填写错误');
		}
		if (empty($content)) {
			$this->writeJson(0, '内容必须填写');
		}
		if (empty($name)) {
			$this->writeJson(0, '姓名必须填写');
		}
		if (empty($mobile)) {
			$this->writeJson(0, '手机号码必须填写');
		}
		$data = [
			'content' => $content,
			'class_name' => $class_name,
			'images' => $images,
			'name' => $name,
			'mobile' => $mobile,
			'user_id' => $this->user_id,
		];
		Advise::create($data);
		$this->writeJson();
	}
	
	function logoff()
	{
		$user = User::findOrFail($this->user_id);
		$user->delete();
		$this->writeJson();
	}
	
	
}
